//package com.ytjj.qmyx.data.service.impl;
//
//import com.ytjj.common.constants.StatisticsConstants;
//import com.ytjj.qmyx.data.service.DataService;
//import com.ytjj.qmyx.mall.model.Channel;
//import lombok.extern.slf4j.Slf4j;
//import org.apache.commons.lang.StringUtils;
//import org.springframework.data.mongodb.core.MongoTemplate;
//import org.springframework.data.mongodb.core.aggregation.Aggregation;
//import org.springframework.data.mongodb.core.aggregation.AggregationResults;
//import org.springframework.data.mongodb.core.query.Criteria;
//import org.springframework.data.mongodb.core.query.Query;
//import org.springframework.data.redis.core.RedisTemplate;
//import org.springframework.stereotype.Service;
//
//import javax.annotation.Resource;
//import java.math.BigDecimal;
//import java.math.RoundingMode;
//import java.time.LocalDate;
//import java.time.LocalDateTime;
//import java.util.*;
//import java.util.stream.Collectors;
//
///**
// *
// *  *
// **/
//@Slf4j
//@Service
//public class DataServiceImpl implements DataService {
//
//    @Resource
//    private PlatformStatisticDao platformStatisticDao;
//
//    @Resource
//    private DataStatisticDao dataStatisticDao;
//
//    @Resource
//    private MongoTemplate mongoTemplate;
//
//    @Resource
//    private RedisTemplate redisTemplate;
//
//    @Resource
//    private AnalysisDao analysisDao;
//
//
//    @Override
//    public DataStatisticsResponse getData(DataStatisticsRequest dataStatisticsRequest) {
//        DataStatisticsResponse dataStatisticsResponse = new DataStatisticsResponse();
//        List<DataResponse> channelData = analysisDao.findDataInfo(dataStatisticsRequest.getPlatform(), dataStatisticsRequest.getChannel(), dataStatisticsRequest.getSearchDate());
//        List<DataResponse> moduleChannelData = analysisDao.findModuleDataList(dataStatisticsRequest.getSearchDate(), dataStatisticsRequest.getChannel());
//        dataStatisticsResponse.setAllChannelDataList(channelData);
//        dataStatisticsResponse.setModuleChannelDataList(moduleChannelData);
//        return dataStatisticsResponse;
//    }
//
//
//    /**
//     * 统计分析 定时任务
//     * @param localDate  == null 时统计昨天整天的数据
//     */
//    @Override
//    public void timing(LocalDate localDate) {
//        boolean timingDay = false;
//        if(null == localDate) {
//            localDate = LocalDate.now().minusDays(1);
//            timingDay = true;
//        }
//        log.info("----开始数据分析----------\n{}", localDate);
//
//        //获取需要统计的渠道
//        Map channelMap = redisTemplate.opsForHash().entries(StatisticsConstants.SKIP_NUM + localDate);
//        if (channelMap == null || channelMap.isEmpty()) return;
//
//        analysisDao.delData(localDate);
//        analysisDao.delDataModule(localDate);
//
//        //分渠道统计
//        for (Object channelName : channelMap.keySet()) {
//            String channel = channelName.toString();
//            log.info("统计渠道名称 ------>channel = {}", channel);
//            if ("all".equals(channel)) continue;
//            String platform = analysisDao.findPlatform(channel);
//            if (StringUtils.isEmpty(platform)) continue;
//            DataStatisticsRequest request = new DataStatisticsRequest(platform, channel, localDate.toString());
//            saveResponse(request);
//        }
//        //各平台聚合统计
//        DataStatisticsRequest request = new DataStatisticsRequest("h5", null, localDate.toString());
//        saveResponse(request);
//        DataStatisticsRequest request1 = new DataStatisticsRequest("android", null, localDate.toString());
//        saveResponse(request1);
//        DataStatisticsRequest request2 = new DataStatisticsRequest("ios", null, localDate.toString());
//        saveResponse(request2);
//        DataStatisticsRequest request3 = new DataStatisticsRequest("weapp", null, localDate.toString());
//        saveResponse(request3);
//
//        if(timingDay) redisTemplate.delete(StatisticsConstants.SKIP_NUM + localDate);
//
//        log.info("----结束数据分析----------\n{}", localDate);
//    }
//
//    @Override
//    public List<Channel> getChannel(String searchDate, String platform) {
//        List<Channel> list = analysisDao.findChannel(searchDate,platform);
//        return list;
//    }
//
//    private void saveResponse(DataStatisticsRequest request) {
//        this.getSearchDate(request);
//        DataStatisticsResponse response = getResponse(request);
//        analysisDao.saveDataList(response.getAllChannelDataList());
//        analysisDao.saveDataModuleList(response.getModuleChannelDataList());
//    }
//
//    /**
//     * 获取统计结果
//     *
//     * @param dataStatisticsRequest
//     * @return
//     */
//    private DataStatisticsResponse getResponse(DataStatisticsRequest dataStatisticsRequest) {
//        DataStatisticsResponse dataStatisticsResponse = new DataStatisticsResponse();
//        List<DataResponse> channelData = this.getChannelData(dataStatisticsRequest);
//        ArrayList<DataResponse> moduleChannelData = this.getModuleChannelData(dataStatisticsRequest);
//        dataStatisticsResponse.setAllChannelDataList(channelData);
//        dataStatisticsResponse.setModuleChannelDataList(moduleChannelData);
//        return dataStatisticsResponse;
//    }
//
//
//    /**
//     * 获取汇总渠道数据
//     *
//     * @param request
//     * @return
//     */
//    public List<DataResponse> getChannelData(DataStatisticsRequest request) {
//        List<DataResponse> channelOrderDataList = new ArrayList<>();
//        if (StringUtils.isNotEmpty(request.getChannel())) {
//            List<String> channelList = this.getChannelList(request.getChannel());
//            List<DataResponse> list = channelList.stream().map(channelItem -> this.channelDataNew(request, request.getSearchDate(), request.getPlatform(), channelItem)).collect(Collectors.toList());
//            channelOrderDataList.addAll(list);
//        } else {
//            DataResponse channelOrderData = this.channelDataNew(request, request.getSearchDate(), request.getPlatform(), request.getChannel());
//            channelOrderDataList.add(channelOrderData);
//        }
//        return channelOrderDataList;
//    }
//
//
//    /**
//     * 获取模块渠道信息
//     *
//     * @param request
//     * @return
//     */
//    public ArrayList<DataResponse> getModuleChannelData(DataStatisticsRequest request) {
//        ArrayList<DataResponse> moduleDataList = new ArrayList<>();
//        // 模块订单信息
//        ActivityEnums[] activityModel = ActivityEnums.values();
//
//        Arrays.asList(activityModel).stream().forEach(item -> {
//            if (StringUtils.isNotEmpty(request.getChannel())) {
//                List<String> channelList = this.getChannelList(request.getChannel());
//                List<DataResponse> list = channelList.parallelStream().map(channelItem -> this.moduleChannelDataNew(request.getSearchDate(), request.getPlatform(), channelItem, item.getActivityCode())).collect(Collectors.toList());
//                moduleDataList.addAll(list);
//            } else {
//                DataResponse channelOrderData = this.moduleChannelDataNew(request.getSearchDate(), request.getPlatform(), request.getChannel(), item.getActivityCode());
//                moduleDataList.add(channelOrderData);
//            }
//        });
//        return moduleDataList;
//    }
//
//    /**
//     * 统计-数据分析统计
//     * 汇总分析
//     *
//     * @param searchDate 统计日期
//     * @param platform   平台
//     * @param channel    渠道
//     * @return
//     */
//    public DataResponse channelDataNew(DataStatisticsRequest request, String searchDate, String platform, String channel) {
//        // 意向订单数
//        Integer intentionOrderNum = getOrderNumber(searchDate, platform, channel, null, null, null, null);
//        // 无地址订单数
//        Integer noAddressOrderNum = getOrderNumber(searchDate, platform, channel, 0, null, null, null);
//        // 支付订单数
//        Integer payOrderNum = getOrderNumber(searchDate, platform, channel, null, 1, null, null);
//        // 实际订单数
//        Integer realOrderNum = intentionOrderNum - noAddressOrderNum;
//        // 转发数
//        Integer transPondNum = getTransPondNum(platform, channel, searchDate);
//
//        DataResponse dateRes = getDateRes(searchDate, platform, channel, null, intentionOrderNum, noAddressOrderNum, payOrderNum, realOrderNum);
//
//        // 激活用户
//        Integer activeUser = platformStatisticDao.getActiveUser(request);
//
//        // 新增用户
//        Integer newAddUser = platformStatisticDao.getNewAddUser(request);
//
//        // 首单人数
//        Integer isFirstBuy = platformStatisticDao.getChannelOrderData(request.getStartTime(), request.getEndTime(), platform, channel, null, 1, 1);
//
//        // 支付总金额
//        BigDecimal payMoney = Optional.ofNullable(platformStatisticDao.getPayMoney(request)).orElse(BigDecimal.ZERO);
//        // 成本
//        BigDecimal costMoney = Optional.ofNullable(platformStatisticDao.getCostMoney(request)).orElse(BigDecimal.ZERO);
//        // 利润
//        BigDecimal profit = payMoney.subtract(costMoney);
//
//        // 意向订单数Uv
//        Integer intentionOrderNumUv = getOrderUvNumber(searchDate, platform, channel, null, null, null, null);
//        // 无地址订单数UV
//        Integer noAddressOrderNumUv = getOrderUvNumber(searchDate, platform, channel, 0, null, null, null);
//        // 支付订单数UV
//        Integer payOrderNumUv= getOrderUvNumber(searchDate, platform, channel, null, 1, null, null);
//
//        setChannelDateRes(dateRes, activeUser, newAddUser, isFirstBuy, payMoney, costMoney, profit, intentionOrderNumUv,noAddressOrderNumUv,transPondNum,payOrderNumUv);
//        return dateRes;
//    }
//
//    public void setChannelDateRes(DataResponse dateRes, Integer activeUser, Integer newAddUser, Integer isFirstBuy,
//                                  BigDecimal payMoney, BigDecimal costMoney, BigDecimal profit, Integer intentionOrderNumUv,
//                                  Integer noAddressOrderNumUv, Integer transPondNum, Integer payOrderNumUv) {
//        dateRes.setActiveUser(activeUser);
//        dateRes.setNewAddUser(newAddUser);
//        dateRes.setIsFirstBuy(isFirstBuy);
//        dateRes.setPayMoney(payMoney);
//        dateRes.setCostMoney(costMoney);
//        dateRes.setProfit(profit);
//        dateRes.setIntentionOrderNumUv(intentionOrderNumUv);
//        dateRes.setNoAddressOrderNumUv(noAddressOrderNumUv);
//        dateRes.setTransPondNum(transPondNum);
//        dateRes.setPayOrderNumUv(payOrderNumUv);
//    }
//
//    /**
//     * 统计-数据分析统计
//     * 模块分析
//     *
//     * @param searchDate 统计日期
//     * @param platform   平台
//     * @param channel    渠道
//     * @return
//     */
//    public DataResponse moduleChannelDataNew(String searchDate, String platform, String channel, String activityCode) {
//        // 意向订单数
//        Integer intentionOrderNum = getOrderNumber(searchDate, platform, channel, null, null, activityCode, null);
//        // 无地址订单数
//        Integer noAddressOrderNum = getOrderNumber(searchDate, platform, channel, 0, null, activityCode, null);
//        // 支付订单数
//        Integer payOrderNum = getOrderNumber(searchDate, platform, channel, null, 1, activityCode, null);
//        // 实际订单数
//        Integer realOrderNum = intentionOrderNum - noAddressOrderNum;
//
//        String pathCode = DataModelEnums.getPathCode(activityCode);
//
//        DataResponse dateRes = getDateRes(searchDate, platform, channel, pathCode, intentionOrderNum, noAddressOrderNum, payOrderNum, realOrderNum);
//        dateRes.setActivityType(ActivityEnums.getActivityType(activityCode));
//        return dateRes;
//    }
//
//    /**
//     * 获取数据分析实体
//     *
//     * @param searchDate
//     * @param platform
//     * @param channel
//     * @param pathCode
//     * @param intentionOrderNum
//     * @param noAddressOrderNum
//     * @param payOrderNum
//     * @param realOrderNum
//     * @return
//     */
//    public DataResponse getDateRes(String searchDate, String platform, String channel, String pathCode,
//                                   Integer intentionOrderNum, Integer noAddressOrderNum, Integer payOrderNum, Integer realOrderNum) {
//        Integer uv = this.getUvNew(searchDate, platform, channel, pathCode);
//        // 订单率 实际订单数/uv
//        BigDecimal orderRatio = uv == 0 ? BigDecimal.ZERO : new BigDecimal(realOrderNum).divide(BigDecimal.valueOf(uv), 4, RoundingMode.HALF_UP);
//        // 支付率 （支付订单/实际订单数）
//        BigDecimal payRatio = realOrderNum == 0 ? BigDecimal.ZERO : new BigDecimal(payOrderNum).divide(BigDecimal.valueOf(realOrderNum), 4, RoundingMode.HALF_UP);
//
//        DataResponse dataResponse = new DataResponse();
//        dataResponse.setChannel(channel);
//        dataResponse.setPlatform(platform);
//        dataResponse.setUv(uv);
//        dataResponse.setIntentionOrderNum(intentionOrderNum);
//        dataResponse.setNoAddressOrderNum(noAddressOrderNum);
//        dataResponse.setPayOrderNum(payOrderNum);
//        dataResponse.setRecordTime(new Date());
//        dataResponse.setOrderRatio(orderRatio);
//        dataResponse.setPayRatio(payRatio);
//        dataResponse.setRealOrderNum(realOrderNum);
//        dataResponse.setTime(searchDate);
//        return dataResponse;
//    }
//
//    /**
//     * 获取转发数
//     *
//     * @param platform
//     * @param channel
//     * @param searchDate
//     * @return
//     */
//    public Integer getTransPondNum(String platform, String channel, String searchDate) {
//        if (PlatformConstant.PLATFORM_H5.equals(platform) || StringUtils.isNotEmpty(channel)) {
//            try {
//                Boolean all = redisTemplate.opsForHash().hasKey(StatisticsConstants.SKIP_NUM + searchDate, "all");
//                if (all) {
//                    if (StringUtils.isNotEmpty(channel)) {
//                        Object o = redisTemplate.opsForHash().get(StatisticsConstants.SKIP_NUM + searchDate, channel);
//                        return o == null ? 0 : Integer.parseInt(o.toString());
//                    } else {
//                        Object o = redisTemplate.opsForHash().get(StatisticsConstants.SKIP_NUM + searchDate, "all");
//                        return o == null ? 0 : Integer.parseInt(o.toString());
//                    }
//                } else {
//                    Criteria criteria = Criteria.where("channel").is(channel);
//                    return (int) mongoTemplate.count(Query.query(criteria), MongoCollectionNameConstants.SKIP + searchDate);
//                }
//            } catch (Exception e) {
//            }
//        }
//        return 0;
//    }
//
//
//    /**
//     * 查询订单数据
//     *
//     * @param searchDate
//     * @param platform
//     * @param channel
//     * @param isAddress
//     * @param isPay
//     * @param activityType
//     * @param isFirstBuy
//     * @return
//     */
//    public int getOrderNumber(String searchDate, String platform, String channel, Integer isAddress, Integer isPay, String activityType, Integer isFirstBuy) {
//        Criteria criteria = Criteria.where("platform").is(platform);
//        if (StringUtils.isNotEmpty(channel)) criteria.and("channel").is(channel);
//        if (StringUtils.isNotEmpty(activityType)) criteria.and("activityType").is(activityType);
//        if (null != isAddress) criteria.and("isAddress").is(isAddress);
//        if (null != isPay) criteria.and("isPay").is(isPay);
//        if (null != isFirstBuy) criteria.and("isFirstBuy").is(isFirstBuy);
//        long count = mongoTemplate.count(Query.query(criteria), MongoCollectionNameConstants.ORDER + searchDate);
//        return (int) count;
//    }
//
//    /**
//     * 查询订单数据
//     *
//     * @param searchDate
//     * @param platform
//     * @param channel
//     * @param isAddress
//     * @param isPay
//     * @param activityType
//     * @param isFirstBuy
//     * @return
//     */
//    public int getOrderUvNumber(String searchDate, String platform, String channel, Integer isAddress, Integer isPay, String activityType, Integer isFirstBuy) {
//        Criteria criteria = Criteria.where("platform").is(platform);
//        if (StringUtils.isNotEmpty(channel)) criteria.and("channel").is(channel);
//        if (StringUtils.isNotEmpty(activityType)) criteria.and("activityType").is(activityType);
//        if (null != isAddress) criteria.and("isAddress").is(isAddress);
//        if (null != isPay) criteria.and("isPay").is(isPay);
//        if (null != isFirstBuy) criteria.and("isFirstBuy").is(isFirstBuy);
//        Aggregation aggregation = Aggregation.newAggregation(
//                Aggregation.match(criteria),
//                Aggregation.group("uuid").count().as("count").last("dayTime").as("dayTime"),
//                Aggregation.group("dayTime").count().as("count")
//        );
//        AggregationResults<Map> results = mongoTemplate.aggregate(aggregation, MongoCollectionNameConstants.ORDER + searchDate, Map.class);
//        List<Map> maps = results.getMappedResults();
//        if (maps.size() == 0) return 0;
//        Object count = maps.get(0).get("count");
//        return Integer.parseInt(count.toString());
//    }
//
//    /**
//     * 获取页面统计uv
//     *
//     * @param searchDate
//     * @param channel
//     * @return
//     */
//    public Integer getUvNew(String searchDate, String platform, String channel, String pathCode) {
//        Criteria criteria = commonCriteria(platform, channel, searchDate, pathCode);
//        Aggregation aggregation = Aggregation.newAggregation(
//                Aggregation.match(criteria),
//                Aggregation.group("uuid").count().as("count").last("dayTime").as("dayTime"),
//                Aggregation.group("dayTime").count().as("count")
//        );
//        AggregationResults<Map> results = mongoTemplate.aggregate(aggregation, MongoCollectionNameConstants.PAGE + searchDate, Map.class);
//        List<Map> maps = results.getMappedResults();
//        if (maps.size() == 0) return 0;
//        Object count = maps.get(0).get("count");
//        return Integer.parseInt(count.toString());
//    }
//
//    /**
//     * 保留
//     *
//     * @param searchDate
//     * @param platform
//     * @param channel
//     * @param moneyProperty
//     * @return
//     */
//    public BigDecimal getMoney(String searchDate, String platform, String channel, String moneyProperty) {
//        Criteria criteria = this.commonCriteria(platform, channel, searchDate, null);
//        Aggregation aggregation = Aggregation.newAggregation(
//                Aggregation.match(criteria),
//                Aggregation.group("isPay").last("isPay").as("isPay").sum(moneyProperty).as("sumNumber")
//        );
//        AggregationResults<Map> results = mongoTemplate.aggregate(aggregation, MongoCollectionNameConstants.ORDER + searchDate, Map.class);
//        List<Map> maps = results.getMappedResults();
//        if (maps.size() == 0) return BigDecimal.ZERO;
//        for (Map map : maps) {
//            if (map.get("isPay").toString().equals("1")) {
//                return new BigDecimal(map.get("sumNumber").toString());
//            }
//        }
//        return BigDecimal.ZERO;
//    }
//
//    /**
//     * 查询时间格式化
//     *
//     * @param dataStatisticsRequest
//     * @return
//     */
//    public void getSearchDate(DataStatisticsRequest dataStatisticsRequest) {
//        LocalDate day = LocalDate.parse(dataStatisticsRequest.getSearchDate());
//        LocalDateTime startTime = day.atStartOfDay();
//        LocalDateTime endTime = startTime.plusDays(1);
//        dataStatisticsRequest.setStartTime(startTime);
//        dataStatisticsRequest.setEndTime(endTime);
//    }
//
//    /**
//     * 获取渠道并且获取渠道的子渠道
//     */
//    public List<String> getChannelList(String channel) {
//        List<String> channelList = new ArrayList<>();
//        channelList.add(channel);
//        List<String> strings = dataStatisticDao.childListByChannel(channel);
//        if (null != strings) channelList.addAll(strings);
//        return channelList;
//    }
//
//    /**
//     * 通用查询 条件拼接
//     */
//    public Criteria commonCriteria(String platform, String channel, String searchDate, String pathCode) {
//        Criteria criteria = Criteria.where("dayTime").is(searchDate);
//        if (StringUtils.isNotEmpty(channel)) criteria.and("channel").is(channel);
//        if (StringUtils.isNotEmpty(platform)) criteria.and("platform").is(platform);
//        if (StringUtils.isNotEmpty(pathCode)) criteria.and("pathCode").is(pathCode);
//        return criteria;
//    }
//
//
//}
